package es.jclm.agri.foragri.services.impl;

import java.io.Serializable;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import es.jclm.agri.foragri.model.Empleado;
import es.jclm.agri.foragri.model.SearchCriteria;
import es.jclm.agri.foragri.services.EmpleadoService;

@Service("empleadoService")
public class EmpleadoJpaService implements EmpleadoService, Serializable {

	private static final long serialVersionUID = 1L;
	
	private EntityManager entityManager;


	@PersistenceContext
	public void setEntityManager(EntityManager entityManager) {
		this.entityManager = entityManager;
	}

	@Transactional
	public void createEmpleado(Empleado empleado) {
		
		entityManager.persist(empleado);
		
	}

	@Transactional
	public void updateEmpleado(Empleado empleado) {
		
		Empleado persistedEmpleado = findById(empleado.getId());
		
		persistedEmpleado.setNombre(empleado.getNombre());
		persistedEmpleado.setApellidos(empleado.getApellidos());
		persistedEmpleado.setDni(empleado.getDni());
		persistedEmpleado.setGenero(empleado.getGenero());
		persistedEmpleado.setFechaNacimiento(empleado.getFechaNacimiento());
		persistedEmpleado.setEmail(empleado.getEmail());
		persistedEmpleado.setTelefono(empleado.getTelefono());
		persistedEmpleado.setPuesto(empleado.getPuesto());
		
		
	}
	
	@Transactional
	public void deleteEmpleado(Empleado empleado){
		
		Empleado persistedEmpleadoWithIdOnly = findById(empleado.getId());
		entityManager.remove(persistedEmpleadoWithIdOnly);
		

	}

	@Transactional(readOnly = true)
	public Empleado findEmpleado(Long empleadoId) {
		
		Empleado empleado = findById(empleadoId);
		
		return empleado;
	}

	@Transactional(readOnly = true)
	@SuppressWarnings("unchecked")
	public List<Empleado> listAll() {	
		return entityManager.createQuery("select x from Empleado x").getResultList();
	}
	
	
	@Transactional(readOnly = true)
	@SuppressWarnings("unchecked")
	public List<Empleado> findEmpleados(SearchCriteria criteria, int firstResult, String orderBy, boolean ascending) {
		String pattern = getSearchPattern(criteria);
		orderBy = (orderBy != null) ? orderBy : "nombre";
		String orderDirection = (ascending) ? " ASC" : " DESC";
		return entityManager
				.createQuery(
						"select h from Empleado h where lower(h.nombre) like :pattern or lower(h.apellidos) like :pattern "
								+ "or lower(h.dni) like :pattern or lower(h.email) like :pattern order by h."
								+ orderBy + orderDirection).setParameter("pattern", pattern)
								.setMaxResults(criteria.getPageSize()).setFirstResult(firstResult).getResultList();
	}
	
	@Transactional(readOnly = true)
	public int getNumberOfEmpleados(SearchCriteria criteria) {
		//String pattern = getSearchPattern(criteria);
		Long count = (Long) entityManager
				.createQuery(
						"select count(h.id) from Empleado h ").getSingleResult();
					
		return count.intValue();
	}
	
	private String getSearchPattern(SearchCriteria criteria) {
		if (StringUtils.hasText(criteria.getSearchString())) {
			return "%" + criteria.getSearchString().toLowerCase().replace('*', '%') + "%";
		} else {
			return "%";
		}
	}
	
	
	@Transactional(readOnly = true)
	public Empleado findById(Long id) {
		return entityManager.find(Empleado.class, id);
	}

}